home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / CaptureParser.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  11KB  |  580 lines

  1. /*
  2. **    CaptureParser.c
  3. **
  4. **    Capture filter parser
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12. typedef BOOL (* SPECIAL_JUMP)(VOID);
  13. typedef BOOL (* __regargs ABORT_JUMP)(register WORD Char);
  14.  
  15. STATIC BOOL        SpecialBackspace(VOID);
  16. STATIC BOOL        SpecialReturn(VOID);
  17. STATIC BOOL        SpecialTab(VOID);
  18. STATIC BOOL        SpecialEsc(VOID);
  19. STATIC BOOL        SpecialCSI(VOID);
  20. STATIC BOOL        AbortCancel(VOID);
  21. STATIC BOOL        AbortEsc(VOID);
  22. STATIC BOOL        AbortCSI(VOID);
  23. STATIC BOOL __regargs    LocalParse(register WORD c);
  24.  
  25.     /* How many characters we will keep in the scan buffer. */
  26.  
  27. #define MAX_SCAN_SIZE    256
  28.  
  29. STATIC struct { UBYTE Key; SPECIAL_JUMP Routine; } LocalSpecialKeys[] =
  30. {
  31.     '\b',    (SPECIAL_JUMP)SpecialBackspace,    /* Erase a character. */
  32.     '\r',    (SPECIAL_JUMP)SpecialReturn,    /* Carriage return. */
  33.     '\t',    (SPECIAL_JUMP)SpecialTab,    /* Move to next tab stop. */
  34.     27,    (SPECIAL_JUMP)SpecialEsc,    /* Start new control sequence. */
  35.     155,    (SPECIAL_JUMP)SpecialCSI    /* Start new control sequence. */
  36. };
  37.  
  38. STATIC SPECIAL_JUMP    *LocalSpecialTable;
  39. STATIC ABORT_JUMP    *LocalAbortTable;
  40.  
  41. STATIC STRPTR        Arnie        = NULL;
  42. STATIC WORD        CharsInBuffer    = 0,
  43.             ScanStep    = 0;
  44. STATIC BOOL        LocalInSequence    = FALSE;
  45. STATIC UBYTE __far    SaveBuffer[MAX_SCAN_SIZE + 1];
  46.  
  47. STATIC UBYTE __far    LocalLineBuffer[BUFFER_LINE_MAX + 1];
  48. STATIC WORD        LocalLineLen,
  49.             LocalLineIndex;
  50.  
  51. STATIC BOOL
  52. SpecialBackspace()
  53. {
  54.     if(LocalLineIndex)
  55.         LocalLineIndex--;
  56.  
  57.     return(FALSE);
  58. }
  59.  
  60. STATIC BOOL
  61. SpecialReturn()
  62. {
  63.     LocalLineIndex = 0;
  64.  
  65.     return(FALSE);
  66. }
  67.  
  68. STATIC BOOL
  69. SpecialTab()
  70. {
  71.     WORD Index = (LocalLineIndex + 7) & ~8;
  72.  
  73.     if(Index > LocalLineLen)
  74.         memset(&LocalLineBuffer[LocalLineLen],' ',Index - LocalLineLen);
  75.  
  76.     LocalLineIndex = Index;
  77.  
  78.     if(Index > LocalLineLen)
  79.         LocalLineLen = Index;
  80.  
  81.     return(FALSE);
  82. }
  83.  
  84. STATIC BOOL
  85. SpecialEsc()
  86. {
  87.     return(TRUE);
  88. }
  89.  
  90. STATIC BOOL
  91. SpecialCSI()
  92. {
  93.     return(LocalParse('['));
  94. }
  95.  
  96. STATIC BOOL
  97. AbortCancel()
  98. {
  99.     LocalInSequence    = FALSE;
  100.     CharsInBuffer    = 0;
  101.     ScanStep    = 0;
  102.  
  103.     return(FALSE);
  104. }
  105.  
  106. STATIC BOOL
  107. AbortEsc()
  108. {
  109.     AbortCancel();
  110.  
  111.     LocalInSequence = TRUE;
  112.  
  113.     return(TRUE);
  114. }
  115.  
  116. STATIC BOOL
  117. AbortCSI()
  118. {
  119.     AbortCancel();
  120.  
  121.     LocalInSequence = TRUE;
  122.  
  123.     return(LocalParse('['));
  124. }
  125.  
  126.     /* LocalParse(UBYTE c):
  127.      *
  128.      *    Input:    A character to be passed through the ANSI code
  129.      *        parser.
  130.      *
  131.      *    Output:    FALSE if input characters did form a valid ANSI
  132.      *        control sequence or if input characters did not
  133.      *        form an ANSI control sequence at all.
  134.      *
  135.      *        TRUE if input characters did possibly introduce
  136.      *        a valid ANSI control sequence.
  137.      */
  138.  
  139. STATIC BOOL __regargs
  140. LocalParse(register WORD c)
  141. {
  142.         /* ScanStep = 0:    This is the first character
  143.          *            to introduce a control sequence.
  144.          */
  145.  
  146.     if(!ScanStep)
  147.     {
  148.         register WORD i;
  149.  
  150.             /* Scan all available codes and try to find
  151.              * a match.
  152.              */
  153.  
  154.         for(i = 0 ; i < NumCodes ; i++)
  155.         {
  156.                 /* This character may introduce a
  157.                  * control sequence.
  158.                  */
  159.  
  160.             if(ANSICode[i] . FirstChar == c)
  161.             {
  162.                     /* If this is a single
  163.                      * character control sequence
  164.                      * call the approriate function
  165.                      * and exit immediately.
  166.                      */
  167.  
  168.                 if(ANSICode[i] . ExactSize == 1)
  169.                 {
  170.                     CharsInBuffer = ScanStep = 0;
  171.  
  172.                     return(FALSE);
  173.                 }
  174.                 else
  175.                 {
  176.                         /* The length of this control
  177.                          * sequence is greater than
  178.                          * a single character. Save
  179.                          * the input character and
  180.                          * return.
  181.                          */
  182.  
  183.                     ScanStep = i;
  184.  
  185.                     SaveBuffer[CharsInBuffer++] = c;
  186.  
  187.                         /* Where to stop. */
  188.  
  189.                     Arnie = ANSICode[i] . Terminator;
  190.  
  191.                     return(TRUE);
  192.                 }
  193.             }
  194.         }
  195.     }
  196.     else
  197.     {
  198.         if(CharsInBuffer < MAX_SCAN_SIZE)
  199.         {
  200.             if(Arnie)
  201.             {
  202.                 register WORD i;
  203.  
  204.                     /* Scan the remaining codes for a match. */
  205.  
  206.                 for(i = ScanStep ; i < NumCodes ; i++)
  207.                 {
  208.                         /* This sequence begins with the
  209.                          * same character the parser was
  210.                          * initialized with, so let's take
  211.                          * a look at it.
  212.                          */
  213.  
  214.                     if(ANSICode[i] . FirstChar == SaveBuffer[0])
  215.                     {
  216.                             /* This character is supposed to
  217.                              * terminate the sequence, so exit.
  218.                              */
  219.  
  220.                         if(Arnie[c])
  221.                         {
  222.                             CharsInBuffer = ScanStep = 0;
  223.  
  224.                             Arnie = NULL;
  225.  
  226.                             return(FALSE);
  227.                         }
  228.                         else
  229.                         {
  230.                                 /* If this character is part of
  231.                                  * a legal sequence store it
  232.                                  * and return.
  233.                                  */
  234.  
  235.                             if(ANSICode[i] . Match[c])
  236.                             {
  237.                                 ScanStep = i;
  238.  
  239.                                 SaveBuffer[CharsInBuffer++] = c;
  240.  
  241.                                 return(TRUE);
  242.                             }
  243.                         }
  244.                     }
  245.                 }
  246.             }
  247.             else
  248.             {
  249.                 register WORD i;
  250.  
  251.                 for(i = ScanStep ; i < NumCodes ; i++)
  252.                 {
  253.                         /* This sequence begins with the
  254.                          * same character the parser was
  255.                          * initialized with, so let's take
  256.                          * a look at it.
  257.                          */
  258.  
  259.                     if(ANSICode[i] . FirstChar == SaveBuffer[0])
  260.                     {
  261.                             /* This character is supposed to
  262.                              * terminate the sequence, so exit.
  263.                              */
  264.  
  265.                         if(ANSICode[i] . LastChar == c)
  266.                         {
  267.                             CharsInBuffer = ScanStep = 0;
  268.  
  269.                             return(FALSE);
  270.                         }
  271.                         else
  272.                         {
  273.                                 /* If this character is part of
  274.                                  * a legal sequence store it
  275.                                  * and return.
  276.                                  */
  277.  
  278.                             if(ANSICode[i] . Match[c])
  279.                             {
  280.                                 ScanStep = i;
  281.  
  282.                                 SaveBuffer[CharsInBuffer++] = c;
  283.  
  284.                                 return(TRUE);
  285.                             }
  286.                         }
  287.                     }
  288.                 }
  289.             }
  290.         }
  291.     }
  292.  
  293.         /* Return failure. */
  294.  
  295.     CharsInBuffer = ScanStep = 0;
  296.  
  297.     Arnie = NULL;
  298.  
  299.     return(FALSE);
  300. }
  301.  
  302. VOID
  303. CaptureParserExit()
  304. {
  305.     if(LocalSpecialTable)
  306.     {
  307.         FreeVecPooled(LocalSpecialTable);
  308.  
  309.         LocalSpecialTable = NULL;
  310.     }
  311.  
  312.     if(LocalAbortTable)
  313.     {
  314.         FreeVecPooled(LocalAbortTable);
  315.  
  316.         LocalAbortTable = NULL;
  317.     }
  318. }
  319.  
  320. BOOL
  321. CaptureParserInit()
  322. {
  323.     if(LocalSpecialTable = (SPECIAL_JUMP *)AllocVecPooled(256 * sizeof(SPECIAL_JUMP),MEMF_ANY | MEMF_CLEAR))
  324.     {
  325.         if(LocalAbortTable = (ABORT_JUMP *)AllocVecPooled(256 * sizeof(ABORT_JUMP),MEMF_ANY | MEMF_CLEAR))
  326.         {
  327.             WORD i;
  328.  
  329.             for(i = 0 ; i < NumElements(LocalSpecialKeys) ; i++)
  330.                 LocalSpecialTable[LocalSpecialKeys[i] . Key] = LocalSpecialKeys[i] . Routine;
  331.  
  332.             for(i = 0 ; i < 256 ; i++)
  333.             {
  334.                 switch(AbortMap[i])
  335.                 {
  336.                     case 0:    LocalAbortTable[i] = LocalParse;
  337.                         break;
  338.  
  339.                     case 1:    LocalAbortTable[i] = (ABORT_JUMP)AbortCancel;
  340.                         break;
  341.  
  342.                     case 2:    LocalAbortTable[i] = (ABORT_JUMP)AbortEsc;
  343.                         break;
  344.  
  345.                     case 3:    LocalAbortTable[i] = (ABORT_JUMP)AbortCSI;
  346.                         break;
  347.                 }
  348.             }
  349.  
  350.             return(TRUE);
  351.         }
  352.     }
  353.  
  354.     return(FALSE);
  355. }
  356.  
  357. VOID __regargs
  358. CaptureParser(register STRPTR Buffer,register LONG Size,register COPTR OutputRoutine)
  359. {
  360.     if(Size > 0)
  361.     {
  362.         register WORD c;
  363.  
  364.         if(Config -> SerialConfig -> StripBit8)
  365.         {
  366.             if(LocalInSequence)
  367.             {
  368.                 register BYTE Result;
  369.  
  370.                 do
  371.                 {
  372.                     c = *Buffer++ & 0x7F;
  373.  
  374.                     Result = (*LocalAbortTable[c])(c);
  375.                 }
  376.                 while(--Size > 0 && Result);
  377.  
  378.                 LocalInSequence = Result;
  379.             }
  380.  
  381.             if(Size > 0)
  382.             {
  383.                 register LONG BufferWidth = Config -> CaptureConfig -> BufferWidth - 1;
  384.  
  385.                 if(Config -> TerminalConfig -> FontMode == FONT_STANDARD)
  386.                 {
  387.                     do
  388.                     {
  389.                         c = (*Buffer++) & 0x7F;
  390.  
  391.                         if(LocalInSequence)
  392.                             LocalInSequence = (*LocalAbortTable[c])(c);
  393.                         else
  394.                         {
  395.                             if(LocalSpecialTable[c])
  396.                                 LocalInSequence = (*LocalSpecialTable[c])();
  397.                             else
  398.                             {
  399.                                 if(c == '\n' || c == '\f' || c == '\v')
  400.                                 {
  401.                                     (*OutputRoutine)(LocalLineBuffer,LocalLineLen);
  402.  
  403.                                     LocalLineIndex = LocalLineLen = 0;
  404.                                 }
  405.                                 else
  406.                                 {
  407.                                     if(IsGlyph[c])
  408.                                     {
  409.                                         LocalLineBuffer[LocalLineIndex++] = c;
  410.  
  411.                                         if(LocalLineIndex > LocalLineLen)
  412.                                             LocalLineLen = LocalLineIndex;
  413.  
  414.                                         if(LocalLineLen > BufferWidth)
  415.                                         {
  416.                                             (*OutputRoutine)(LocalLineBuffer,LocalLineLen);
  417.  
  418.                                             LocalLineIndex = LocalLineLen = 0;
  419.                                         }
  420.                                     }
  421.                                 }
  422.                             }
  423.                         }
  424.                     }
  425.                     while(--Size > 0);
  426.                 }
  427.                 else
  428.                 {
  429.                     do
  430.                     {
  431.                         c = (*Buffer++) & 0x7F;
  432.  
  433.                         if(LocalInSequence)
  434.                             LocalInSequence = (*LocalAbortTable[c])(c);
  435.                         else
  436.                         {
  437.                             if(LocalSpecialTable[c])
  438.                                 LocalInSequence = (*LocalSpecialTable[c])();
  439.                             else
  440.                             {
  441.                                 if(c == '\n' || c == '\f' || c == '\v')
  442.                                 {
  443.                                     (*OutputRoutine)(LocalLineBuffer,LocalLineLen);
  444.  
  445.                                     LocalLineIndex = LocalLineLen = 0;
  446.                                 }
  447.                                 else
  448.                                 {
  449.                                     if(c)
  450.                                     {
  451.                                         LocalLineBuffer[LocalLineIndex++] = c;
  452.  
  453.                                         if(LocalLineIndex > LocalLineLen)
  454.                                             LocalLineLen = LocalLineIndex;
  455.  
  456.                                         if(LocalLineLen > BufferWidth)
  457.                                         {
  458.                                             (*OutputRoutine)(LocalLineBuffer,LocalLineLen);
  459.  
  460.                                             LocalLineIndex = LocalLineLen = 0;
  461.                                         }
  462.                                     }
  463.                                 }
  464.                             }
  465.                         }
  466.                     }
  467.                     while(--Size > 0);
  468.                 }
  469.             }
  470.         }
  471.         else
  472.         {
  473.             if(LocalInSequence)
  474.             {
  475.                 register BYTE Result;
  476.  
  477.                 do
  478.                 {
  479.                     c = *Buffer++;
  480.  
  481.                     Result = (*LocalAbortTable[c])(c);
  482.                 }
  483.                 while(--Size > 0 && Result);
  484.  
  485.                 LocalInSequence = Result;
  486.             }
  487.  
  488.             if(Size > 0)
  489.             {
  490.                 register LONG BufferWidth = Config -> CaptureConfig -> BufferWidth - 1;
  491.  
  492.                 if(Config -> TerminalConfig -> FontMode == FONT_STANDARD)
  493.                 {
  494.                     do
  495.                     {
  496.                         c = *Buffer++;
  497.  
  498.                         if(LocalInSequence)
  499.                             LocalInSequence = (*LocalAbortTable[c])(c);
  500.                         else
  501.                         {
  502.                             if(LocalSpecialTable[c])
  503.                                 LocalInSequence = (*LocalSpecialTable[c])();
  504.                             else
  505.                             {
  506.                                 if(c == '\n' || c == '\f' || c == '\v')
  507.                                 {
  508.                                     (*OutputRoutine)(LocalLineBuffer,LocalLineLen);
  509.  
  510.                                     LocalLineIndex = LocalLineLen = 0;
  511.                                 }
  512.                                 else
  513.                                 {
  514.                                     if(IsGlyph[c])
  515.                                     {
  516.                                         LocalLineBuffer[LocalLineIndex++] = c;
  517.  
  518.                                         if(LocalLineIndex > LocalLineLen)
  519.                                             LocalLineLen = LocalLineIndex;
  520.  
  521.                                         if(LocalLineLen > BufferWidth)
  522.                                         {
  523.                                             (*OutputRoutine)(LocalLineBuffer,LocalLineLen);
  524.  
  525.                                             LocalLineIndex = LocalLineLen = 0;
  526.                                         }
  527.                                     }
  528.                                 }
  529.                             }
  530.                         }
  531.                     }
  532.                     while(--Size > 0);
  533.                 }
  534.                 else
  535.                 {
  536.                     do
  537.                     {
  538.                         c = *Buffer++;
  539.  
  540.                         if(LocalInSequence)
  541.                             LocalInSequence = (*LocalAbortTable[c])(c);
  542.                         else
  543.                         {
  544.                             if(LocalSpecialTable[c])
  545.                                 LocalInSequence = (*LocalSpecialTable[c])();
  546.                             else
  547.                             {
  548.                                 if(c == '\n' || c == '\f' || c == '\v')
  549.                                 {
  550.                                     (*OutputRoutine)(LocalLineBuffer,LocalLineLen);
  551.  
  552.                                     LocalLineIndex = LocalLineLen = 0;
  553.                                 }
  554.                                 else
  555.                                 {
  556.                                     if(c)
  557.                                     {
  558.                                         LocalLineBuffer[LocalLineIndex++] = c;
  559.  
  560.                                         if(LocalLineIndex > LocalLineLen)
  561.                                             LocalLineLen = LocalLineIndex;
  562.  
  563.                                         if(LocalLineLen > BufferWidth)
  564.                                         {
  565.                                             (*OutputRoutine)(LocalLineBuffer,LocalLineLen);
  566.  
  567.                                             LocalLineIndex = LocalLineLen = 0;
  568.                                         }
  569.                                     }
  570.                                 }
  571.                             }
  572.                         }
  573.                     }
  574.                     while(--Size > 0);
  575.                 }
  576.             }
  577.         }
  578.     }
  579. }
  580.